﻿using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using WMSSystem.JWT;
using WMSSystem.YSL.Dto.LoginDto;
using WMSSystem.YSL.Interfance;
using WMSSystem.YSL.Dto.JWT;
using JwtSettings = WMSSystem.JWT.JwtSettings;
namespace WMSSystem.YSL
{
    /// <summary>
    /// JWT服务实现类
    /// 优化后只包含必要的用户信息：id、userName、phoneNumber、realName
    /// </summary>
    public class JwtService : IJwtService, ITransientDependency
    {
        private readonly JwtSettings _jwtSettings;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="jwtSettings">JWT配置</param>
        public JwtService(IOptions<JwtSettings> jwtSettings)
        {
            _jwtSettings = jwtSettings.Value;
        }

        /// <summary>
        /// 生成JWT令牌
        /// 只返回访问令牌字符串
        /// </summary>
        /// <param name="user">用户信息</param>
        /// <returns>JWT访问令牌字符串</returns>
        public async Task<string> GenerateTokenAsync(LoginResultDto user)
        {
            try
            {
                // 验证配置
                if (string.IsNullOrEmpty(_jwtSettings.SecretKey))
                {
                    throw new InvalidOperationException("JWT SecretKey 未配置");
                }

                if (string.IsNullOrEmpty(_jwtSettings.Issuer))
                {
                    throw new InvalidOperationException("JWT Issuer 未配置");
                }

                if (string.IsNullOrEmpty(_jwtSettings.Audience))
                {
                    throw new InvalidOperationException("JWT Audience 未配置");
                }

                // 创建声明，只包含必要的用户信息
                var claims = new[]
                {
                    new Claim("id", user.Id.ToString()),
                    new Claim("userName", user.UserName ?? ""),
                    new Claim("phoneNumber", user.PhoneNumber ?? ""),
                    new Claim("realName", user.RealName ?? ""),
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                    new Claim(JwtRegisteredClaimNames.Iat, DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(), ClaimValueTypes.Integer64)
                };

                // 创建密钥
                var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_jwtSettings.SecretKey));
                var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

                // 创建令牌描述符
                var tokenDescriptor = new SecurityTokenDescriptor
                {
                    Subject = new ClaimsIdentity(claims),
                    Expires = DateTime.UtcNow.AddMinutes(_jwtSettings.ExpirationMinutes),
                    Issuer = _jwtSettings.Issuer,
                    Audience = _jwtSettings.Audience,
                    SigningCredentials = creds
                };

                // 生成令牌
                var tokenHandler = new JwtSecurityTokenHandler();
                var token = tokenHandler.CreateToken(tokenDescriptor);
                var tokenString = tokenHandler.WriteToken(token);

                return await Task.FromResult(tokenString);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"JWT令牌生成异常: {ex.Message}");
                Console.WriteLine($"异常堆栈: {ex.StackTrace}");
                throw; // 重新抛出异常，让上层处理
            }
        }

        /// <summary>
        /// 验证JWT令牌
        /// </summary>
        /// <param name="token">JWT令牌</param>
        /// <returns>验证结果</returns>
        public async Task<bool> ValidateTokenAsync(string token)
        {
            try
            {
                var tokenHandler = new JwtSecurityTokenHandler();
                var key = Encoding.UTF8.GetBytes(_jwtSettings.SecretKey);

                tokenHandler.ValidateToken(token, new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(key),
                    ValidateIssuer = _jwtSettings.ValidateIssuer,
                    ValidIssuer = _jwtSettings.Issuer,
                    ValidateAudience = _jwtSettings.ValidateIssuer,
                    ValidAudience = _jwtSettings.Audience,
                    ValidateLifetime = _jwtSettings.ValidateIssuer,
                    ClockSkew = TimeSpan.FromSeconds(_jwtSettings.ClockSkewSeconds)
                }, out SecurityToken validatedToken);

                return await Task.FromResult(true);
            }
            catch
            {
                return await Task.FromResult(false);
            }
        }

        /// <summary>
        /// 刷新JWT令牌
        /// </summary>
        /// <param name="refreshToken">刷新令牌</param>
        /// <returns>新的JWT令牌信息</returns>
        public async Task<JwtTokenDto> RefreshTokenAsync(string refreshToken)
        {
            // 这里可以添加刷新令牌的验证逻辑
            // 为了简化，这里直接返回null，表示需要重新登录
            return await Task.FromResult<JwtTokenDto>(null);
        }

        /// <summary>
        /// 从令牌中获取用户ID
        /// </summary>
        /// <param name="token">JWT令牌</param>
        /// <returns>用户ID</returns>
        public string GetUserIdFromToken(string token)
        {
            try
            {
                var tokenHandler = new JwtSecurityTokenHandler();
                var jwtToken = tokenHandler.ReadJwtToken(token);
                return jwtToken.Claims.FirstOrDefault(x => x.Type == "id")?.Value;
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 从令牌中获取用户信息
        /// </summary>
        /// <param name="token">JWT令牌</param>
        /// <returns>用户信息</returns>
        public LoginResultDto GetUserFromToken(string token)
        {
            try
            {
                var tokenHandler = new JwtSecurityTokenHandler();
                var jwtToken = tokenHandler.ReadJwtToken(token);

                // 从令牌中提取用户信息
                var id = jwtToken.Claims.FirstOrDefault(x => x.Type == "id")?.Value;
                var userName = jwtToken.Claims.FirstOrDefault(x => x.Type == "userName")?.Value;
                var phoneNumber = jwtToken.Claims.FirstOrDefault(x => x.Type == "phoneNumber")?.Value;
                var realName = jwtToken.Claims.FirstOrDefault(x => x.Type == "realName")?.Value;

                if (string.IsNullOrEmpty(id) || string.IsNullOrEmpty(userName))
                {
                    return null;
                }

                return new LoginResultDto
                {
                    Id = Guid.Parse(id),
                    UserName = userName,
                    PhoneNumber = phoneNumber ?? "",
                    RealName = realName ?? "",
                    StatusCode = 200,
                    Message = "令牌有效"
                };
            }
            catch
            {
                return null;
            }
        }

        /// <summary>
        /// 生成刷新令牌
        /// </summary>
        /// <returns>刷新令牌</returns>
        private string GenerateRefreshToken()
        {
            var randomNumber = new byte[32];
            using (var rng = System.Security.Cryptography.RandomNumberGenerator.Create())
            {
                rng.GetBytes(randomNumber);
                return Convert.ToBase64String(randomNumber);
            }
        }
    }
}
